Asset Tools - (Assetic Python SDK)
Introduction
The Assetic Python SDK contains a set of tools that simplify common integration tasks for assets. An asset is comprised of the asset record itself and within the asset are components. Within each component are network measures (see also Asset Integration Overview).
The Asset Tools wrap this data structure into a single object representation "assetic.AssetToolsCompleteAssetRepresentation". This allows all details of an asset to be prepared and passed to a single tool for complete asset creation or update. This representation is also used when retrieving an asset via these tools.
Asset Tools Module
The Assetic Python SDK contains a module called assetic.AssetTools
Within that module are the following key methods:
- get_complete_asset
- create_complete_asset
- update_complete_asset
AssetToolsCompleteAssetRepresentation
The Asset representation has the following structure:
- asset_representation
- an instance of "assetic.Assetic3IntegrationRepresentationsComplexAssetRepresentation"
- components
- a list array of "AssetToolsComponentRepresentation" instances
Within each "component" instance is:
- component_representation
- an instance of "assetic.Assetic3IntegrationRepresentationsComponentRepresentation"
- dimensions
- a list array of "Assetic3IntegrationRepresentationsComponentDimensionRepresentation"
Get Complete Asset
The following code sample gets an asset, including components and dimension details
- """
- Get an asset including component and dimensions using the SDK asset tools
- (Assetic.AssetsGetCompleteSDK.py)
- """
- import assetic
- #Assetic SDK instance
- asseticsdk=assetic.AsseticSDK("c:/users/you/assetic.ini", None,"Info")
- #Tools API
- assettools = assetic.AssetTools()
- assetid = "411142055"
- attributes = ["Zone","Comment"]
- asset = assettools.get_complete_asset(assetid,attributes)
- print(asset)
Update Complete Asset
To simplify the update process, the Assetic Python SDK handles the complexity of all the core fields being updated. The following code sample utilises the Assetic Python SDK tool "update_complete_asset". This tool wraps the API endpoints for asset, component, and dimension creation. It gets the current values for the asset, component, and dimension prior to the update and applies those values to fields that are NULL in the update object passed into this method. The update object is an instance of "assetic.AssetToolsCompleteAssetRepresentation". This object allows setting of the asset, component, and dimension values that are to be updated, values that are not to be updated are left as NULL in the object.
If only the asset is to be updated then the "assetic.AssetToolsComponentRepresentation" object within the "assetic.AssetToolsCompleteAssetRepresentation" instance is left as an empty array. Likewise the dimension object within "assetic.AssetToolsComponentRepresentation" may be left as NULL if the component is to be updated but not the dimensions.
The following code sample updates an asset with components and dimensions.
- """
- Update an asset, component and dimensions
- (Assetic.AssetsPutComplete.py)
- """
- import assetic
- # Define location of configuration file, log file, log level
- asseticsdk=assetic.AsseticSDK("c:/users/you/assetic.ini", None, "Info")
- # Asset Tools API
- assettools = assetic.AssetTools()
- def main(assetguid,componentguid,dimensionguid):
- """
- Update the asset, components, and component dimensions
- """
- ##instantiate the complete asset representation
- complete_asset_obj = assetic.AssetToolsCompleteAssetRepresentation()
- #create an instance of the complex asset object
- asset = assetic.Assetic3IntegrationRepresentationsComplexAssetRepresentation()
- ##set asset guid to update
- asset.id = assetguid
- ##set fields to update
- asset.asset_external_identifier = "upd"
- attributes = {"Comment":"a revised comment","Link":"www.assetic.com"}
- asset.attributes = attributes
- ##Set the asset_representation to the defined asset values
- complete_asset_obj.asset_representation = asset
- ##array list to put component plus dimensions
- components_and_dims = []
- #instantiate complete component representation
- component_obj = assetic.AssetToolsComponentRepresentation()
- ##create an instance of the component representation
- component = assetic.Assetic3IntegrationRepresentationsComponentRepresentation()
- component.id = componentguid
- ##set fields to update
- component.design_life = 50
- component_obj.component_representation = component
- ##create an array for the dimensions to be added to the component
- dimlist = []
- ##Create an instance of the dimension and set minimum fields
- dim = assetic.Assetic3IntegrationRepresentationsComponentDimensionRepresentation()
- #set the id fields
- dim.id = dimensionguid
- dim.component_id = componentguid
- #set the field to update
- dim.network_measure = 5
- ##append to dimension array
- dimlist.append(dim)
- ##Add the dimension array to the component
- component_obj.dimensions = dimlist
- ##Add component to the list
- components_and_dims.append(component_obj)
- ##add the component & dims array to the complete asset object
- complete_asset_obj.components = components_and_dims
- ##update the complete asset
- errcode = assettools.update_complete_asset(complete_asset_obj,False)
- if errcode > 0:
- return
- print("success")
- ##This will run the method main() to kickstart it all
- if __name__ == "__main__":
- #set the IDs
- assetguid = "88439a40-6e1e-e711-946c-06edd62954d7"
- componentguid = "8e439a40-6e1e-e711-946c-06edd62954d7"
- dimensionguid = "90439a40-6e1e-e711-946c-06edd62954d7"
- #execute the main function
- main(assetguid,componentguid,dimensionguid)
Note that in the above sample there were updates to network measure, components, and the asset itself.
Create Asset
The following code sample utilises the Assetic Python SDK tool "create_complete_asset". This tool wraps the API endpoints for asset, component, and dimension creation.
This code sample illustrates the creation of an asset, 2 components within that asset, and 2 dimension records within each component.
It utilises the "assetic.AssetToolsCompleteAssetRepresentation" object model to define the asset, components, and dimensions. There are checks made to ensure the mandatory fields are not empty.
The response is the same object with the generated ID's included.
It is not mandatory for dimensions and components to be defined in the assetic.AssetToolsCompleteAssetRepresentation object.
- """
- Create an asset, component and dimensions
- (Assetic.AssetsPostComplete.py)
- """
- import assetic
- from datetime import datetime #use to generate a unique asset id
- # Assetic SDK instance
- asseticsdk=assetic.AsseticSDK("c:/users/you/assetic.ini",None,"Debug")
- #Asset Tools API
- assettools = assetic.AssetTools()
- def main():
- """
- Create the asset, components, and component dimensions
- Assumes the category does not have autonumber
- """
- ##generate an id based on the current time
- dt = datetime.now()
- assetid = "{0}{1}{2}{3}{4}".format(
- dt.month,dt.day,dt.hour,dt.minute,dt.second)
- ##instantiate the complete asset representation
- complete_asset_obj = assetic.AssetToolsCompleteAssetRepresentation()
- #create an instance of the complex asset object
- asset = assetic.Assetic3IntegrationRepresentationsComplexAssetRepresentation()
- ##mandatory fields
- asset.asset_category="Roads"
- asset.status = "Active"
- asset.asset_id = assetid
- asset.asset_name = "RD{0}".format(assetid)
- complete_asset_obj.asset_representation = asset
- ##array list to put component plus dimensions
- components_and_dims = []
- #instantiate complete component representation
- component_obj = assetic.AssetToolsComponentRepresentation()
- ##create an instance of the component representation
- component = assetic.Assetic3IntegrationRepresentationsComponentRepresentation()
- componentname = "{0}CMP1".format(assetid)
- component.asset_id = assetid
- component.label = "Main Label" #"Component Name in UI
- component.component_type = "Main"
- component.dimension_unit = "Metre"
- component.network_measure_type = "Length"
- #optional fields
- component.design_life = 50
- component.external_identifier = "Ext{0}".format(componentname)
- component.material_type = "Concrete" #must exist
- ##Add the component to the components
- component_obj.component_representation = component
- ##create an array for the dimensions to be added to the component
- dimlist = []
- ##Create an instance of the dimension and set minimum fields
- dim = assetic.Assetic3IntegrationRepresentationsComponentDimensionRepresentation()
- dim.network_measure = 75.7
- dim.unit = "Metre"
- dim.record_type = "Info" #could also be "Subtraction" or "Info"
- dim.network_measure_type = "Length"
- ##can also include additional fields
- dim.comments = "Created via API"
- dim.multiplier = 2.5 #will default as 1 if undefined
- dimlist.append(dim)
- ##Create an instance of the dimension and set minimum fields
- dim = assetic.Assetic3IntegrationRepresentationsComponentDimensionRepresentation()
- dim.network_measure = 3
- dim.unit = "Metre"
- dim.record_type = "Subtraction" #could also be "Subtraction" or "Info"
- dim.network_measure_type = "Length"
- ##can also include additional fields
- dim.comments = "Created via API"
- dim.multiplier = 1 #will default as 1 if undefined
- dimlist.append(dim)
- ##Add the dimension array to the component
- component_obj.dimensions = dimlist
- ##Add component to the list
- components_and_dims.append(component_obj)
- #instantiate complete component representation
- component_obj = assetic.AssetToolsComponentRepresentation()
- ##Create another component
- componentname = "{0}CMP2".format(assetid)
- component = assetic.Assetic3IntegrationRepresentationsComponentRepresentation()
- component.name = componentname
- component.asset_id = assetid
- component.label = "Formation"
- component.component_type = "Formation"
- component.dimension_unit = "Metre"
- component.network_measure_type = "Length"
- #optional fields
- component.design_life = 50
- component.external_identifier = "Ext{0}".format(componentname)
- #component.material_type = "Concrete" #must exist
- component_obj.component_representation = component
- ##create an array for the dimensions to be added to the component
- dimlist = []
- ##Create an instance of the dimension and set minimum fields
- dim = assetic.Assetic3IntegrationRepresentationsComponentDimensionRepresentation()
- dim.network_measure = 50
- dim.component_id = componentname
- dim.unit = "Metre"
- dim.record_type = "Addition" #could also be "Subtraction" or "Info"
- dim.network_measure_type = "Length"
- ##can also include additional fields
- dim.comments = "Created via API"
- dim.multiplier = 2 #will default as 1 if undefined
- dimlist.append(dim)
- ##Create an instance of the dimension and set minimum fields
- dim = assetic.Assetic3IntegrationRepresentationsComponentDimensionRepresentation()
- dim.network_measure = 5
- dim.component_id = componentname
- dim.unit = "Metre"
- dim.record_type = "Subtraction" #could also be "Subtraction" or "Info"
- dim.network_measure_type = "Length"
- ##can also include additional fields
- dim.comments = "Created via API"
- dim.multiplier = 3 #will default as 1 if undefined
- dimlist.append(dim)
- ##Add the dimension array to the component
- component_obj.dimensions = dimlist
- ##Add component with dims to the list
- components_and_dims.append(component_obj)
- ##add the component & dims array to the complete asset object
- complete_asset_obj.components = components_and_dims
- ##create the complete asset
- response = assettools.create_complete_asset(complete_asset_obj)
- if len(response.components) > 0:
- #get some ID's
- assetguid = response.asset_representation.id
- #first component
- componentguid = response.components[0].component_representation.id
- #first dimension
- dimensionguid = response.components[0].dimensions[0].id
- def create_asset(assetid,category,name,status):
- """
- Create an asset for the given asset ID and category
- :param assetid: Assetic user friendly asset ID
- :param assetid: asset category name
- :param assetid: asset name
- :param assetid: status - "Active" or "Pending"
- :return: asset response object or None
- """
- asseticsdk.logger.info("Create the asset {0}".format(assetid))
- #create an instance of the complex asset object
- asset = assetic.Assetic3IntegrationRepresentationsComplexAssetRepresentation()
- ##mandatory fields
- asset.asset_category=category
- asset.status = status
- asset.asset_id = assetid
- asset.asset_name = name
- ##now execute the request
- try:
- newasset = assetapi.complex_asset_post(asset)
- except assetic.rest.ApiException as e:
- if e.status == 400:
- msg = "Bad Request. Status {0}, Reason: {1} {2}".format(
- e.status,e.reason,e.body)
- asseticsdk.logger.error(msg)
- else:
- asseticsdk.logger.error("Status {0}, Reason: {1} {2}".format(
- e.status,e.reason,e.body))
- return None
- return newasset
- def create_component(assetid,componentname):
- """
- Create an component for the given asset ID and component name
- :param assetid: Assetic component GUID or user friendly component ID
- :param componentname: Assetic component name
- :return: component response object or None
- """
- asseticsdk.logger.info("Create the component {0}".format(componentname))
- #create instance of component and set minimum values
- component = assetic.Assetic3IntegrationRepresentationsComponentRepresentation()
- component.name = componentname
- component.asset_id = assetid
- component.label = "Main"
- component.component_type = "Main"
- component.dimension_unit = "Metre"
- component.network_measure_type = "Length"
- #optional fields
- component.design_life = 50
- component.external_identifier = "Ext{0}".format(componentname)
- component.material_type = "Concrete" #must exist
- try:
- component = componentapi.component_post(component)
- except assetic.rest.ApiException as e:
- if e.status == 400:
- msg = "Component for Component GUID {0} not found".format(assetguid)
- asseticsdk.logger.error(msg)
- else:
- msg = "Status {0}, Reason: {1} {2}".format(e.status,e.reason,e.body)
- asseticsdk.logger.error(msg)
- return None
- return component
- def create_dimension(componentid,measure):
- """
- Create a dimension for the given component ID
- :param assetid: Assetic component GUID or user friendly component ID
- :param measure: The measure to apply to the dimension
- :return: dimension response object or None
- """
- asseticsdk.logger.info("Create the dimensions for component {0}".format(
- componentid))
- ##Create an instance of the dimension and set minimum fields
- dim = assetic.Assetic3IntegrationRepresentationsComponentDimensionRepresentation()
- dim.network_measure = measure
- dim.unit = "Metre"
- dim.record_type = "Addition" #could also be "Subtraction" or "Info"
- dim.network_measure_type = "Length"
- ##can also include additional fields
- dim.comments = "Created via API"
- dim.multiplier = 2 #will default as 1 if undefined
- try:
- newdim = componentapi.component_post_dimension(componentid,dim)
- except assetic.rest.ApiException as e:
- if e.status == 404:
- msg = "Dimensions for Component {0} not found".format(assetguid)
- asseticsdk.logger.error(msg)
- else:
- msg = "Status {0}, Reason: {1} {2}".format(e.status,e.reason,e.body)
- asseticsdk.logger.error(msg)
- return None
- return newdim
- ##This will run the method main() to kickstart it all
- if __name__ == "__main__":
- main()